This ebook contains few lesser known Python gems. As usual, I will try to keep them updated and will continue to expand. If you wish to add any new, send them to me at (funmayank @ yahoo . co . in).
In [206]:
a = 10
b = "TEST"
a, b = b, a
print(a, b)
Python 3 allows to have unicode identifier's, which allows non-english speaking users to code.
In [216]:
हिन्दी = 10
print(हिन्दी)
round
is a function to round off the numbers and its normal usage is as follows
In [2]:
num = round(283746.32321, 1)
print(num)
The second parameter defines the decimal number to which the number to rounded of. But if we provide a -ve number
to it then it starts rounding of the number itself instead of decimal digit as shown in the below example
In [3]:
num = round(283746.32321, -2)
print(num)
num = round(283746.32321, -1)
print(num)
num = round(283746.32321, -4)
print(num)
In [4]:
x, y, z = 1019292929191, 1029228322, 222224
pow(x, y, z)
Out[4]:
In [5]:
# Do not run this, please. it will take forever.
##### (x ** y) % z
In python we can have multiple ways to achieve multi line strings.
In [6]:
txt = """The Supreme Lord said: The indestructible, transcendental living
entity is called Brahman and his eternal nature is called the
self. Action pertaining to the development of these material
bodies is called karma, or fruitive activities."""
In [7]:
print(txt)
In [8]:
txt = ("The Supreme Lord said: The indestructible, transcendental living"
"entity is called Brahman and his eternal nature is called the "
"self. Action pertaining to the development of these material"
"bodies is called karma, or fruitive activities.")
In [9]:
print(txt)
In [10]:
txt = "The Supreme Lord said: The indestructible, transcendental living " \
"entity is called Brahman and his eternal nature is called the"
print(txt)
using string
multiply with int
results in concatinating string that number of times. Lets print a line on console using -
.
In [2]:
print("~^*" * 10)
In [12]:
print("ash" in "ashwini")
In [3]:
print("ash" is ['a', 's', 'h'])
In [4]:
print("ash" is ('a', 's', 'h'))
In [14]:
print("ash" is 'ash')
In [15]:
### Implicit concatenation without "+" operator
In [5]:
name = "Mayank" " " "Johri"
print(name)
In [12]:
try:
name = "Mayank" " " "Johri" ' .'
print(name)
except SyntaxError:
pass
In [14]:
list_cities = ["Bhopal", "New Delhi", "Agra", "Mumbai", "Aligarh", "Hyderabad"]
# Lets join the list of string in string using `join`
str_cities = ", ".join(list_cities)
print(str_cities)
In [15]:
list_cities = ("Bhopal", "New Delhi", "Agra", "Mumbai", "Aligarh", "Hyderabad")
# Lets join the list of string in string using `join`
str_cities = ", ".join(list_cities)
print(str_cities)
There are few methods to reverse the string, but two are most common
In [17]:
txt = "The Mother Earth"
print(txt[::-1])
In [16]:
txt = "The Mother Earth"
print("".join(list(reversed(txt))))
In [18]:
a, b, *remaining = (1, 2, 3, 4, 5, "test")
print(a, b)
print(remaining)
In [19]:
a, b, *remaining = [1, 2, 3, 4, 5, "test"]
print(a, b)
print(remaining)
In [20]:
first,*middle,last = (1, 2, 3, 4, 5, 6, 7, 8)
print(first, last)
print(middle)
In [21]:
first,*middle,last = [1, 2, 3, 4, 5, 6, 7, 8]
print(first, last)
print(middle)
similar to String we can literally multiply string and tuples with integer as shown below
In [22]:
lst = [1, 2, 3]
print(lst * 3)
In [23]:
lst = (1, 2, 3)
print(lst * 3)
In [25]:
a = [(1,2), (3,4), (5,6)]
print(list(zip(a)))
print("*" * 33)
print(list(zip(*a)))
In [31]:
a = [(1, 2, 7),
(3, 4, 8),
(5, 6, 9)]
print(list(zip(a)))
print("*" * 33)
print(list(zip(*a)))
In [28]:
lst = ["Ashwini", "Banti", "Bhaiya", "Mayank", "Shashank", "Rahul" ]
list(enumerate(lst))
Out[28]:
Now, lets change the starting index to 10
In [29]:
print(list(enumerate(lst, 10)))
built-in
keyword reversed
allows the list to be reversed.
In [34]:
lst = [1, 2, 3, 4, 53]
print(list(reversed(lst)))
In [35]:
print(lst[::-1])
In [45]:
l = [[1,2], [3], [4,5], [6], [7, 8, 9]]
l1 = [[1,2], 3, [4,5], [6], [7, 8, 9]]
l2 = [[1,2], [3], [4,5], [6], [[7, 8], 9], 10]
In [39]:
from itertools import chain
flattened_list = list(chain(*l))
print(flattened_list)
NOTE: this method will fail if any of the element is non list item as shown in the below example
In [41]:
from itertools import chain
try:
flattened_list = list(chain(*l1))
print(flattened_list)
except:
print("Error !!!")
In [44]:
from itertools import chain
flattened_list = list(chain(*l2))
print(flattened_list)
In [163]:
flattened_list = [y for x in l for y in x]
print(flattened_list)
NOTE: this method will fail if any of the element is non list item as shown in the below example
In [190]:
flattened_list = [y for x in l1 for y in x]
print(flattened_list)
Lets update code to handle this situation
In [193]:
flattened_list = [si for i in l1 for si in (i if isinstance(i, list) else [i])]
print(flattened_list)
In [161]:
flattened_list = sum(l, [])
print(flattened_list)
NOTE: this method will fail if any of the element is non list item as shown in the below example
In [148]:
sum(l1, [])
In [160]:
flattened_list = []
for x in l:
for y in x:
flattened_list.append(y)
print(flattened_list)
NOTE: this method will fail if any of the element is non list item as shown in the below example
In [166]:
flattened_list = []
for x in l1:
for y in x:
flattened_list.append(y)
print(flattened_list)
In [196]:
from functools import reduce
flattened_list = reduce(lambda x, y: x + y, l)
print(flattened_list)
NOTE: this method will fail if any of the element is non list item as shown in the below example
In [197]:
flattened_list = reduce(lambda x, y: x + y, l1)
print(flattened_list)
In [186]:
import operator
flattened_list = reduce(operator.add, l)
print(flattened_list)
NOTE: this method will fail if any of the element is non list item as shown in the below example
In [187]:
import operator
flattened_list = reduce(operator.add, l1)
print(flattened_list)
In [157]:
lst = [1, 2]
lst.append(lst)
print(lst)
lets check if really we have infinite recursion, with the following code. We should get RuntimeError: maximum recursion depth exceeded in comparison
error later in the execution.
def test(lst):
for a in lst:
if isinstance(a, list):
print("A", a)
test(a)
print(a)
test(lst)
In [200]:
ori = [1, 2, 3, 4, 5, 6]
dup = ori
print(id(ori))
print(id(dup))
Both the variables are still pointing to same list, thus change in one will change another also.
In [201]:
dup.insert(0, 29)
print(ori)
print(dup)
In [47]:
ori = [1, 2, 3, 4, 5, 6]
dup = ori[:]
print(id(ori))
print(id(dup))
In [58]:
dup.insert(0, 29)
print(ori)
print(dup)
!!! ouch moment !!!
In [55]:
ori = [1, 2, 3, [4], 5, 6]
dup = ori[:]
print(id(ori))
print(id(dup))
In [67]:
ori[3].append(10)
print(ori)
print(dup)
print(id(ori[3]))
print(id(dup[4]))
print(id(ori))
print(id(dup))
rescue using Deep copy
In [66]:
from copy import deepcopy
ori = [1, 2, 3, [4], 5, 6]
dup = deepcopy(ori)
print(ori)
print(dup)
print(id(ori[3]))
print(id(dup[3]))
print(id(ori))
print(id(dup))
ori[3].append(10)
print(ori)
print(dup)
print(id(ori[3]))
print(id(dup[3]))
print(id(ori))
print(id(dup))
In [70]:
states_capitals = {'MP': 'Bhopal', 'UP': 'Lucknow', 'Rajasthan': 'Jaipur'}
In [117]:
capitals_states = dict(zip(*list(zip(*states_capitals.items()))[::-1]))
print(capitals_states)
In [71]:
capitals_states = dict([v, k] for k, v in states_capitals.items())
print(capitals_states)
In [123]:
capitals_states = dict(zip(states_capitals.values(), states_capitals.keys()))
print(capitals_states)
In [72]:
capitals_states = {states_capitals[k] : k for k in states_capitals}
print(capitals_states)
Multiple methods can be used to create a dictionary. We are going to cover few of the cool ones.
In [31]:
states = ["MP", "UP", "Rajasthan"]
capitals = ["Bhopal", "Lucknow", "Jaipur"]
states_capitals = dict(zip(states, capitals))
print(states_capitals)
In [32]:
states_capitals = dict(MP='Bhopal', Rajasthan='Jaipur', UP='Lucknow')
print(states_capitals)
In [59]:
states_capitals = dict([('MP', 'Bhopal'), ('UP', 'Lucknow'), ('Rajasthan', 'Jaipur')])
print(states_capitals)
In [229]:
a = {'MP': 'Bhopal', 'UP': 'Lucknow', 'Rajasthan': 'Jaipur'}
b = {'Jaipur': 'Rajasthan', 'Bhopal': 'MP', 'Lucknow': 'UP'}
c = a.copy()
c.update(b)
print(c)
# for Python >= 3.5: https://www.python.org/dev/peps/pep-0448
c = {**b, **a}
print(c)
In [ ]:
def double_bubble(x):
yield x
yield x*x
d = {k:v for k, v in double_bubble}
In [78]:
{chr(97+i)*2 : i for i in range(5)}
Out[78]:
In [33]:
y = 10
x = 3 if (y == 1) else 2
print(x)
In [34]:
x = 3 if (y == 1) else 2 if (y == -1) else 1
print(x)
In [35]:
def foo(x=[]):
x.append(1)
print(x)
foo()
foo()
foo()
In [73]:
# instead use:
def fun(x=None):
if x is None:
x = []
x.append(1)
print(x)
fun()
fun()
fun()
TODO: Add more examples
In [37]:
def draw_point(x, y):
"""You can unpack a list or a dictionary as
function arguments using * and **."""
print(x, y)
point_foo = (3, 4)
point_bar = {'y': 3, 'x': 2}
draw_point(*point_foo)
draw_point(**point_bar)
In [76]:
def letsEcho():
test = "Hello"
print(test)
letsEcho.test = "Welcome"
print(letsEcho.test)
letsEcho()
print(letsEcho.test)
In [126]:
def dum_dum():
try:
return '`dum dum` returning from try'
finally:
return '`dum dum` returning from finally'
print(dum_dum())
In [136]:
class Test():
def __getattribute__(self, name):
f = lambda: " ".join([name, name[::-1]])
return f
t = Test()
# New attribute created at runtime
t.rev()
Out[136]:
In [77]:
x = 5
In [79]:
1 < x < 100
Out[79]:
In [81]:
1 < x > 100
Out[81]:
In [83]:
1 > x > 100
Out[83]:
In [84]:
1 > x < 100
Out[84]:
In [42]:
10 < x < 20
Out[42]:
In [88]:
x < 10 < x*10 < 100
Out[88]:
In [90]:
x < 10 < x*10 < 50
Out[90]:
In [91]:
x < 10 < x*10 <= 50
Out[91]:
In [44]:
10 > x <= 9
Out[44]:
In [93]:
5 == x > 4
Out[93]:
In [94]:
x == 5 > 4
Out[94]:
Wrap an iterable with enumerate and it will yield the item along with its index.
In [48]:
a = ['a', 'b', 'c', 'd', 'e']
for index, item in enumerate(a): print (index, item)
https://www.python.org/dev/peps/pep-0342/, also please reaad http://www.dabeaz.com/coroutines/
In [49]:
def mygen():
"""Yield 5 until something else is passed back via send()"""
a = 5
while True:
f = (yield a) #yield a and possibly get f in return
if f is not None:
a = f #store the new value
g = mygen()
print(next(g))
print(next(g))
g.send(7)
print(next(g))
print(next(g))
g.send(17)
print(next(g))
print(next(g))
In [50]:
def seek_next_line(f):
"""
The iter(callable, until_value) function repeatedly calls
callable and yields its result until until_value is returned.
"""
for c in iter(lambda: f.read(1),'\n'):
pass
In [95]:
try:
with open('a', 'w') as a, open('b', 'w') as b:
pass
except IOError as e:
print ('Operation failed: %s' % e.strerror)
In [212]:
#### write file using `print`
In [215]:
with open("outfile.txt" , "w+") as outFile:
print('Modern Standard Hindi is a standardised and sanskritised register of the Hindustani language.', file=outFile)
In [54]:
# Python 2 syntax
try:
some_operation()
except SomeError, e:
if is_fatal(e):
raise
handle_nonfatal(e)
In [55]:
def some_operation():
raise Exception
def is_fatal(e):
return True
# Python 3 syntax
try:
some_operation()
except Exception as e:
if is_fatal(e):
raise
handle_nonfatal(e)
In [56]:
from __future__ import braces
In [205]:
import __hello__
In [57]:
import codecs
s = 'The Zen of Python, by Tim Peters'
enc = codecs.getencoder( "rot-13" )
dec = codecs.getdecoder("rot-13")
os = enc( s )[0]
print(os)
print(dec(os)[0])
In [58]:
import this